﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Framework.Reflection.Controller;
using System.Reflection;
using System.Reflection.Emit;
using Pixysoft.Framework.Reflection.Core;
using System.Data;
using Pixysoft.TestDrivens;
using System.Xml.Serialization;

namespace Pixysoft.Framework.Reflection.testdriven
{
    [TestDriven]
    class Class_Pojo
    {
        public void test001()
        {
            IPojoValue o = ReflectionManager.CreatePojo<IPojoValue>();
            o.Name = "hello";
            o.Names.Add("hello");
            Console.WriteLine(o.Name);
            Console.WriteLine(o.Names[0]);

            IPojoObject2 oo = ReflectionManager.CreatePojo<IPojoObject2>();
        }

        //proxy vs emit performance
        public void test002()
        {
            //100000
            //proxy
            //    Time Elapsed:		3,085ms
            //    CPU time:		2,812,500,000ns
            //    Gen 0: 			499
            //    Gen 1: 			0
            //    Gen 2: 			0

            //dproxy dynamic constructor
            //    Time Elapsed:		127ms
            //    CPU time:		109,375,000ns
            //    Gen 0: 			47
            //    Gen 1: 			0
            //    Gen 2: 			0

            //direct
            //    Time Elapsed:		6ms
            //    CPU time:		0ns
            //    Gen 0: 			2
            //    Gen 1: 			0
            //    Gen 2: 			0




            Pixysoft.Tools.CodeTimer.Initialize();

            Pixysoft.Tools.CodeTimer.Time("proxy", 100000, delegate()
            {
                IPojoValue proxy = Pixysoft.Tools.PojoHelper.GetPojo<IPojoValue>();
                proxy.Name = "123123";
                string name = proxy.Name;
            });

            Pixysoft.Tools.CodeTimer.Time("dproxy dynamic constructor", 100000, delegate()
            {
                IPojoValue dproxy = ReflectionManager.CreatePojo<IPojoValue>();
                dproxy.Name = "123123";
                string dname = dproxy.Name;
            });


            Pixysoft.Tools.CodeTimer.Time("direct", 100000, delegate()
            {
                IPojoValue real = new PojoValue();
                real.Name = "123123";
                string dname = real.Name;
            });
        }

        //interface enum/binary
        [TestCase]
        public static void test003()
        {
            IPojoEnum pojo = ReflectionManager.CreatePojo<IPojoEnum>();
            pojo.Type = PojoTestType.B;
            Assert.SaveOrVerify("pojo.enum", pojo.Type);
            pojo.Image = new byte[] { 1, 2, 3 };
            Assert.SaveOrVerify("pojo.binary", pojo.Image);
        }

        //interface object
        //[TestCase]
        public static void test004()
        {
            IPojoObject pojo = ReflectionManager.CreatePojo<IPojoObject>();
            pojo.Object = new DataTable();
            Console.WriteLine(pojo.Object);
            //Assert.SaveOrVerify("pojo.object", pojo.Object);
        }

        //interface interface
        [TestCase]
        public static void test005()
        {
            IPojoObject pojo = ReflectionManager.CreatePojo<IPojoObject>();
            IPojoObject ipojo = ReflectionManager.CreatePojo<IPojoObject>();
            ipojo.IObject = pojo;
            Console.WriteLine(ipojo.IObject);
            Assert.SaveOrVerify("pojo.interface", ipojo.IObject);
        }
    }

    public interface IPojoObject
    {
        DataTable Object
        {
            get;
            set;
        }

        IPojoObject IObject
        {
            get;
            set;
        }
    }

    [XmlRoot]
    public interface IPojoEnum
    {
        PojoTestType Type { get;set;}

        byte[] Image { get;set;}
    }

    [XmlRoot]
    public interface IPojoValue
    {
        string Name { get;set;}

        byte[] Image { get;set;}

        List<string> Names { get;set;}
    }

    class PojoValue : IPojoValue, ICloneable
    {
        public PojoValue()
        {
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public object Create()
        {
            return new PojoValue();
        }

        string name;
        List<string> list = new List<string>();

        public byte[] Image
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        public object Clone()
        {
            return new PojoValue();
        }

        #region IPojoValue 成员


        public List<string> Names
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        #endregion
    }

    public enum PojoTestType
    {
        A, B,
    }

    public interface IPojoBase
    {
        DateTime CreateDate { get;set;}
    }

    public interface IPojoObject2 : IPojoBase
    {
        string Name { get;set;}
    }
}
